﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Permissions;
using mshtml;

namespace HtmlReader
{
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public sealed class HtmlElement
    {
        internal HtmlElement(object domElement, HtmlDocument document)
        {
            Document = document;
            DomElement = domElement;
        }

        #region Common Properties
        public object DomElement { get; private set; }
        public HtmlDocument Document { get; private set; }

        public bool CanHaveChildren
        {
            get
            {
                IHTMLElement2 element2 = DomElement as IHTMLElement2;
                return element2.canHaveChildren;
            }
        }

        public bool Enabled
        {
            get
            {
                IHTMLElement3 element3 = DomElement as IHTMLElement3;
                return !element3.disabled;
            }
        }

        public string Id
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.id;
            }
        }

        public string InnerHtml
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.innerHTML;
            }
        }

        public string InnerText
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.innerText;
            }
        }

        public string Name
        {
            get
            {
                return GetAttribute("Name");
            }
        }

        public HtmlElement NextSibling
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                IHTMLElement parent = element.parentElement;
                for (int i = 0; i < parent.children.length - 1; i++)
                {
                    IHTMLElement child = parent.children[i] as IHTMLElement;
                    if (child.Equals(element))
                        return Document.Dictionary[parent.children[i + 1].GetHashCode()];
                }
                return null;
            }
        }

        public string OuterHtml
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.outerHTML;
            }
        }

        public string OuterText
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.outerText;
            }
        }

        public HtmlElement Parent
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return Document.Dictionary[element.parentElement.GetHashCode()];
            }
        }

        private IHTMLStyle Style
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.style;
            }
        }

        public short TabIndex
        {
            get
            {
                IHTMLElement2 element = DomElement as IHTMLElement2;
                return element.tabIndex;
            }
        }

        public string TagName
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                return element.tagName;
            }
        }

        public HtmlElementCollection All
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                IHTMLElementCollection all = element.all;
                return new HtmlElementCollection(ref all, Document);
            }
        }

        public HtmlElementCollection Children
        {
            get
            {
                IHTMLElement element = DomElement as IHTMLElement;
                IHTMLElementCollection children = element.children;
                return new HtmlElementCollection(ref children, Document);
            }
        }

        public HtmlElement FirstChild
        {
            get
            {
                return Children.Count == 0 ? null : Children[0];
            }
        }
        #endregion

        #region Special Properties
        public string Href
        {
            get
            {
                IHTMLAnchorElement anchor = DomElement as IHTMLAnchorElement;
                if (anchor == null)
                    return null;
                else
                    return anchor.href;
            }
        }
        #endregion

        public string GetAttribute(string attributeName)
        {
            IHTMLElement element = DomElement as IHTMLElement;
            return element.getAttribute("Name", 2);
        }

        public HtmlElementCollection GetElementsByTagName(string tagName)
        {
            return null;
        }

        public override bool Equals(Object obj)
        {
            HtmlDocument element = obj as HtmlDocument;
            if (element == null)
                return false;

            return element.GetHashCode() == DomElement.GetHashCode();
        }

        public override int GetHashCode()
        {
            return DomElement.GetHashCode();
        }
    }
}
